<script lang="ts" setup>
/**
 * Expose
 * @change 手动切换当前act key值
 *
 * Props
 * @config tabs配置项 --IConfig [{ key: string, label: string }, ...]
 * 必传
 *
 * @width 组件宽度
 * 默认100%
 *
 * @height 组件高度
 * 默认100vh
 *
 * @key 当前active
 * 默认config第一项key值
 *
 * @hiddenLabel 隐藏label
 * 默认 false
 *
 * @sliding 滑动切换
 * 默认 true
 *
 * Emits
 * @tab 返回当前key值
 *
 * Slot 内容区域 slot-name = config[n].key
 */
import { computed, getCurrentInstance, nextTick, reactive, ref, watch } from 'vue'
import type { ComponentInternalInstance } from 'vue'
import { hasUnit, throttle } from '@U/common'
import type { IObj, IObjArray, PropType } from '@/interface'

interface IConfig {
  label: string,
  key: any,
}
const { proxy: _this } = getCurrentInstance() as ComponentInternalInstance
const props = defineProps({
  key: {
    type: String,
    required: false,
    default: '',
  },
  width: {
    type: String,
    required: false,
    default: '',
  },
  height: {
    type: String,
    required: false,
    default: '',
  },
  sliding: {
    type: Boolean,
    required: false,
    default: true,
  },
  config: {
    type: Object as PropType<Array<IConfig>>,
    required: true,
  },
  hiddenLabel: {
    type: Boolean,
    required: false,
    default: false,
  },
})
const emits = defineEmits(['tab'])
// 当前act
const act = ref(props?.key || props?.config[0].key)
// 切换tab
const change = (key: string) => {
  act.value = key
  emits('tab', key)
}
defineExpose({
  change,
})
// 当前组件宽度
const tabsWidth = ref(<number>0)
const actWidth = ref(<number>0)
const elQuery = uni.createSelectorQuery().in(_this)

nextTick(() => {
    elQuery.select('.prm-tab-content')
        .boundingClientRect((d: IObj) => {
          tabsWidth.value = d.width
        })
        .exec()
  if (!props?.hiddenLabel) {
    elQuery
        .select('.prm-tab-line')
        .boundingClientRect((d: IObj) => {
          actWidth.value = d.width
        })
        .exec()
  }
})

// 监听手指滑动
// const onTouch = ref(false)
// const touchState = reactive(<IObj>{
//   start: 0,
//   move: 0,
//   end: 0,
// })
// function touching(site: IObj, type: string) {
//   if (site?.touches && site.touches[0]?.clientX) {
//     touchState[type] = site.touches[0].clientX
//   }
//   if (type === 'start') {
//     onTouch.value = true
//   }
//   if (type === 'end') {
//     onTouch.value = false
//     setTimeout(() => {
//       touchState.start = 0
//       touchState.move = 0
//       touchState.end = 0
//     }, 400)
//   }
// }
// 手指滑动的距离
// const touchDistance = computed(() => (Math.floor(Math.abs(touchState.start - touchState.move))))
// 手指滑动方向 0 从左到右 | 1 从右到左
// const touchDirection = computed(() => ((touchState.start - touchState.move) < 0 ? 0 : 1))
// 手指滑动最终距离相对组件宽度的百分比
// const touchPercent = computed(() => (Math.floor((Math.abs(touchState.start - touchState.end) / tabsWidth.value) * 100)))

// tab数量
const tabNumber = computed(() => props.config.length)
// 当前act位置数量
const actNumber = computed(() => (props.config as Array<IConfig>)?.map((d: IConfig) => d.key).indexOf(act.value))

// act平移距离
const actLineDistance = ref(0)
// tab平移距离
const tabDistance = ref(0)

// 点击视图移动
watch(
    () => `${actNumber.value}${actWidth.value}`,
    () => {
      // 标签区域
      actLineDistance.value = (actNumber.value * (tabsWidth.value / tabNumber.value)) + ((tabsWidth.value / tabNumber.value) - actWidth.value) / 2
      // 内容区域
      tabDistance.value = tabsWidth.value * actNumber.value
    },
)
// 滑动视图移动
// watch(
//     () => touchDistance.value,
//     () => {
//       // logTouch()
//       if (onTouch.value) {
//         console.log(touchDirection.value ? '从右到左' : '从左到右', touchDistance.value)
//       }
//       // 标签区域
//       // 内容区域
//       // let distance = 0
//       // if (touchDirection.value && (tabDistance.value < ((tabNumber.value - 1) * tabsWidth.value))) {
//       //   distance = touchDistance.value
//       // }
//       // console.log(distance)
//       // tabDistance.value += distance
//     },
// )

</script>

<template>
  <div :style="{width: `${width ? hasUnit(width) : '100%'}`, height: `${height ? hasUnit(height) : '100vh'}`}" class="prm-tabs">
    <div v-if="!hiddenLabel" class="prm-tab">
      <div :style="{left: `${actLineDistance}px`}" class="prm-tab-line" />
      <div
        v-for="d in config"
        :key="d.key"
        :class="{'act': act === d.key}"
        class="prm-tab-item"
        @tap="change(d.key)"
      >
        {{ d.label }}
      </div>
    </div>
    <div class="prm-tab-content">
      <div
        :style="{left: `-${tabDistance}px`, transition: `all .3s`}"
        class="prm-tab-box"
      >
        <!--
            @touchend="touching($event, 'end')"
            @touchmove="touching($event, 'move')"
            @touchstart="touching($event, 'start')"
        -->
        <template
          v-for="tab in config"
          :key="tab.key"
        >
          <div class="prm-tab-content-item">
            <slot :name="tab.key" />
          </div>
        </template>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.prm-tabs {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  .prm-tab {
    width: 100%;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: #ffffff;
    position: relative;
    .prm-tab-item {
      flex: 1 1;
      font-size: 32rpx;
      text-align: center;
      height: 90rpx;
      line-height: 90rpx;
      transition: color .3s;
      color: #00000073;
    }
    .act {
      font-weight: bold;
      color: rgba(0, 0, 0, 0.85);
    }
    .prm-tab-line {
      position: absolute;
      bottom: 0;
      width: 80rpx;
      height: 8rpx;
      // background: #ff8002;
      background: #1890FF;
      border-radius: 4rpx;
      transition: all .3s;
    }
  }
  .prm-tab-content {
    width: 100%;
    height: 100%;
    flex: 1 1;
    overflow-x: hidden;
    position: relative;
    background-color: #fff;
    .prm-tab-box {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      display: flex;
      .prm-tab-content-item {
        flex: 0 0 100%;
        height: 100%;
      }
    }
  }
}
</style>
